//src > hooks > index.ts
import { watch } from 'vue';
import { useStore, Store } from 'vuex';
import {
  SET_TODO,
  SET_TODO_LIST,
  REMOVE_TODO,
  SET_TODO_STATUS,
  SET_DOING_STATUS
} from '@/store/actionTypes';
import { ITodo, TODO_STATUS } from '@/typings';

//**设计观：**

// TodoList是一个方法集合，增加/删除/展示列表/更改状态，实际上都在操作列表，应该自定义一个hook API，来管理这些方法的解决方案，让TodoList形成一个方案集合，导出一些方法，让其在各个组件都可以单独导入某些方法去执行相应的程序

export interface IUseTodo {
  setTodo: (value: string) => void;
  setTodoList: () => void;
  removeTodo: (id: number) => void;
  setStatus: (id: number) => void;
  setDoing: (id: number) => void;
}

export interface IUseLocalStorage {
  getLocalList: () => ITodo[];
  setLocalList: (todoList: ITodo[]) => void;
}

//钩子1：TodoList相关的hooks方法
function useTodo(): IUseTodo {
  const store: Store<any> = useStore();
  const { getLocalList, setLocalList }: IUseLocalStorage = useLocalStorage();
  const todoList: ITodo[] = getLocalList();

  //监听数据变化 有变化时重新加载页面的列表
  watch(
    () => {
      return store.state.list;
    },
    (todoList) => {
      setLocalList(todoList);
    }
  );

  function setTodo(value: string): void {
    //1.组装输入框value到一个对象{id:xxx,content:xxx,status:'willdo'}
    const todo: ITodo = {
      id: new Date().getTime(),
      content: value,
      status: TODO_STATUS.WILLDO
    };

    //2.将组装好的对象存入state
    store.dispatch(SET_TODO, todo);

    //3.调用自定义hooks里的setLocalList方法进行保存state列表到本地列表数组里
    // setLocalList(store.state.list);
    /**
     * [
     *   {
     *     "id": 1638890393325,
     *     "content": "333",
     *     "status": "willdo"
     *   },
     *   ...
     * ]
     */
  }

  function setTodoList() {
    //将localStorage拿到的数组修改为list数组
    store.dispatch(SET_TODO_LIST, todoList);
  }

  function removeTodo(id: number): void {
    //将todolist-item子组件传递过来的事件方法重新改为hook钩子底下的方法
    //从而在hooks钩子底下的方法实现业务逻辑
    //派发到actions去修改state.list底下的数据
    store.dispatch(REMOVE_TODO, id);

    //重新加载列表
    // setLocalList(store.state.list);
  }

  function setStatus(id: number): void {
    //点击复选框，点击state.list.status就为finished/否则willdo
    store.dispatch(SET_TODO_STATUS, id);

    //重新加载列表
    // setLocalList(store.state.list);
  }

  function setDoing(id: number): void {
    store.dispatch(SET_DOING_STATUS, id);

    //重新加载列表
    // setLocalList(store.state.list);
  }

  //返回导出解决方案
  return {
    //方案1：组装修改Todo,设置到列表里
    setTodo,
    //方案2：刷新页面列表(挂载组件时)读取loacalStorage里的todoList显示在页面的列表项里
    setTodoList,
    //方案3：删除
    removeTodo,
    //方案4：更改待办/未做的状态
    setStatus,
    //方案5：更改正在做的状态
    setDoing
  };
}

//钩子2：本地存储的hooks方法
function useLocalStorage(): IUseLocalStorage {
  function getLocalList(): ITodo[] {
    return JSON.parse(localStorage.getItem('todoList') || '[]');
  }

  function setLocalList(todoList: ITodo[]): void {
    localStorage.setItem('todoList', JSON.stringify(todoList));
  }

  return {
    //方案1：获取localStorage里的todoList
    getLocalList,
    //方案2：设置todoList保存到localStorage里
    setLocalList
  };
}

export { useTodo, useLocalStorage };
